import { useState, useEffect, useRef } from 'react';
import styles from './index.less';
import { Tabs, Button, TimePicker } from 'antd';
import moment from 'moment';
import { connect } from 'umi';

import { TRAlert, TRDefault, TRMessage } from '#/components';
import { HttpCode } from '#/utils/contacts';
import { downloadHandle } from '#/utils/utils';
import { deleteIcon, plus, exportIcon, lock } from '@/assets';
import { fail, lock as lock2, partSuccess, success, submitting } from '@/assets/rollingBatch';
import { exportProgram } from '@/pages/Tianji/RollingBatch/services';
import { PlusOutlined, UploadOutlined } from '@ant-design/icons';
import { PROGARM_STATUS } from '../../constant/enums';
import messageConstant from '../../constant/message';
import { SEQUENCE_TRADE_TIME_PATTERN } from '../../constant';
import {
  ProgramSetting,
  SubmitStatusModal,
  PowerValidationModal,
  TradeStrategyValidationModal,
} from '../index';
import {
  getDisabledTimelyFuncJson,
  clone,
  createProgramExistValid,
  validPower,
  validSubmitTime,
  validTradeStrategy,
} from '../../utils';

const { TabPane } = Tabs;

// 在这个组件中保存、申报、定时申报方案
const Main = ({
  permissions,
  tradeCenterTime,
  currentUnitList,
  programList,
  hasModified,
  currentProgramInfo,
  currentSequenceDate,
  currentSequenceInfo,
  currentProgramHourOrderList,
  powerLimitInfo,
  dispatch,
}) => {
  const submitStatusRef = useRef(),
    powerValidationModalRef = useRef(),
    tradeStrategyValidationModalRef = useRef();

  const initTimer = {
    format: 'HH:mm',
    value: null,
    lock: false,
    timerComVisible: false,
  };

  const [timer, setTimer] = useState(initTimer);

  // 监听定时变化
  useEffect(() => {
    if (currentProgramInfo?.status === PROGARM_STATUS.TIMELY) {
      setTimer({ ...timer, lock: true, value: moment(currentProgramInfo?.timelySubmitTime) });
    } else {
      setTimer(initTimer);
    }
  }, [JSON.stringify(currentProgramInfo)]);

  /**
   * 判断方案的申报按钮是否可用
   * @returns
   */
  const validSubmitButtonDisabled = () => {
    return validSaveButtonDisabled();
  };

  /**
   * 判断方案的保存按钮是否可用
   * @returns
   */
  const validSaveButtonDisabled = () => {
    if (!permissions.modify) {
      return true;
    }
    switch (currentProgramInfo?.status) {
      case PROGARM_STATUS.CREATE:
      case PROGARM_STATUS.SAVE:
      case PROGARM_STATUS.FAIL:
        return false;
      default:
        return true;
    }
  };

  /**
   * 判断定时按钮是否可用
   * @returns
   */
  const validTimelyButtonDisabled = () => {
    if (!permissions.modify) {
      return true;
    }
    switch (currentProgramInfo?.status) {
      case PROGARM_STATUS.CREATE:
      case PROGARM_STATUS.SAVE:
      case PROGARM_STATUS.TIMELY:
      case PROGARM_STATUS.FAIL:
        return false;
      default:
        return true;
    }
  };

  /**
   * 切换方案
   * @param {*} id
   */
  const changeCurrentProgram = async (id) => {
    if (id === currentProgramInfo?.id) return;
    if (
      hasModified &&
      (await TRAlert.show(messageConstant.LOST_MODIFY_PROGRAM_CONTENT_WARNING_MESSAGE)).index === 0
    )
      return;
    // 切换方案
    dispatch({ type: 'rollingBatch/changeCurrentProgram', payload: { programId: id } });
  };

  /**
   * 新增方案
   */
  const addProgram = async () => {
    if (
      hasModified &&
      (await TRAlert.show(messageConstant.LOST_MODIFY_PROGRAM_CONTENT_WARNING_MESSAGE)).index === 0
    )
      return;
    createProgramExistValid(programList, () =>
      dispatch({ type: 'rollingBatch/initNewProgramAndChoose' }),
    );
  };

  /**
   * 保存、定时申报、立即申报方案 0:保存,1:定时申报,2:立即申报
   * @param {*} type
   * @param {*} time
   */
  const submitProgram = async (type, time) => {
    // 按钮权限判断
    let { save, timely, submit } = permissions;

    if ((type === 0 && !save) || (type === 1 && !timely) || (type === 2 && !submit)) {
      TRMessage.info(messageConstant.NO_BUTTON_PERMISSION_WARNING_MESSAGE);
      return;
    }

    // 交易单元不能为空
    if (!currentUnitList.length) {
      TRMessage.warning(messageConstant.NO_UNIT_SELECT_WARNING_MESSAGE);
      return;
    }

    // 立即提交验证交易时间
    if (type === 2) {
      // 验证交易时间
      if (!validSubmitTime(moment(tradeCenterTime), currentSequenceInfo)) {
        TRMessage.error('选择交易日申报时间未开始或已经结束，请在交易申报时间范围进行申报');
        return;
      } else if (
        moment(tradeCenterTime).isAfter(
          moment(currentSequenceInfo.endTimeFirst).subtract(20, 'm'),
        ) &&
        moment(tradeCenterTime).isAfter(moment(currentSequenceInfo.endTimeSecond).subtract(20, 'm'))
      ) {
        TRMessage.error(
          '选择交易日申报时间应早于申报结束时间前20分钟,请在交易申报时间范围进行申报',
        );
        return;
      }
    }

    // 定时提交至少比当前时间晚8分钟
    if (type === 1) {
      let timelyTime = moment(time).subtract(15, 'm');
      if (moment(new Date()).isAfter(timelyTime)) {
        TRMessage.error('选择交易日定时时间应距离当前时间至少15分钟,请调整后重新定时');
        return;
      } else if (!validSubmitTime(moment(timelyTime), currentSequenceInfo)) {
        TRMessage.error('当前定时时间不在序列申报时间内，请重新定时');
        return;
      } else if (
        moment(timelyTime).isAfter(moment(currentSequenceInfo.endTimeFirst).subtract(8, 'm')) &&
        moment(tradeCenterTime).isAfter(moment(currentSequenceInfo.endTimeSecond).subtract(8, 'm'))
      ) {
        TRMessage.error('定时申报时间应早于申报结束时间前8分钟,请在规范定时时间范围进行定时申报');
        return;
      }
    }

    // 交易方向校验
    if (!currentProgramInfo.adjustFlag) {
      if (!tradeStrategyValidation()) return;
      powerValidation({ operateType: type, timelySubmitTime: time });
    } else {
      dispatch({
        type: 'rollingBatch/submitProgram',
        payload: { operateType: type, timelySubmitTime: time },
      });
    }
  };

  /**
   * 删除方案
   * @param {*} id
   * @param {*} e
   * @returns
   */
  const deleteProgramFunc = async (programId, e) => {
    e.stopPropagation();
    if (
      hasModified &&
      programId === currentProgramInfo.id &&
      (await TRAlert.show(messageConstant.LOST_MODIFY_PROGRAM_CONTENT_WARNING_MESSAGE)).index === 0
    )
      return;
    if ((await TRAlert.eamDelete(messageConstant.DELETE_PROGRAM_CONFIRM_MESSAGE)).index === 0)
      return;
    dispatch({ type: 'rollingBatch/deleteProgram', payload: { programId } });
  };

  /**
   * 交易方向校验
   */
  const tradeStrategyValidation = () => {
    let validResult = validTradeStrategy(
      currentProgramHourOrderList,
      powerLimitInfo,
      currentUnitList,
    );
    if (!validResult?.result) {
      tradeStrategyValidationModalRef.current.initHandle(validResult);
      return false;
    }
    return true;
  };

  /**
   * 是否有超出限额的场站校验
   * @returns
   */
  const powerValidation = async (payload) => {
    // 如果选择了接受限额调剂，则不进行校验，返回true
    if (currentProgramInfo.adjust) return true;
    let validResult = validPower(currentProgramHourOrderList, currentUnitList, powerLimitInfo);
    if (!validResult?.result) {
      powerValidationModalRef.current.initHandle(validResult, payload);
    } else {
      dispatch({ type: 'rollingBatch/submitProgram', payload });
    }
  };

  /**
   * 渲染方案的图标
   * @param {*} item
   * @returns
   */
  const renderProgramStatusIcon = ({ status }) => {
    const { FAIL, TIMELY, SUBMITTING, PART_SUCCESS, SUCCESS } = PROGARM_STATUS;
    switch (status) {
      case FAIL:
        return <img className={styles.programStatus} src={fail} />;
      case TIMELY:
        return <img className={styles.programStatus} src={lock2} />;
      case SUBMITTING:
        return <img className={styles.programStatus} src={submitting} />;
      case PART_SUCCESS:
        return <img className={styles.programStatus} src={partSuccess} />;
      case SUCCESS:
        return <img className={styles.programStatus} src={success} />;
      default:
        return '';
    }
  };

  /**
   * 渲染方案的删除按钮
   * @param {} param0
   * @returns
   */
  const renderProgramDeleteIcon = ({ remove, status, id }) => {
    if (remove) {
      switch (status) {
        case PROGARM_STATUS.CREATE:
        case PROGARM_STATUS.SAVE:
        case PROGARM_STATUS.FAIL:
          return (
            <img
              className={styles.deleteIcon}
              src={deleteIcon}
              onClick={(e) => deleteProgramFunc(id, e)}
            />
          );
      }
    }
    return '';
  };

  /**
   * 设置、取消定时申报弹框的显示
   */
  const handleTimer = async () => {
    if (timer.lock) {
      let obj = await TRAlert.eamDelete('是否取消当前定时申报');
      if (obj.index === 1) {
        changeTimer(false);
      }
    } else {
      let data = clone(timer);
      data.timerComVisible = true;
      setTimer(data);
    }
  };
  /**
   * 定时按钮失去焦点
   */
  const hideTimerCom = () => {
    let data = clone(timer);
    if (data.timerComVisible) {
      data.timerComVisible = false;
      setTimer(data);
    }
  };

  /**
   * 导出方案
   * @returns
   */
  const exportProgramAsync = async () => {
    let { status, id } = currentProgramInfo;
    // 新建方案无法导出方案
    if (status === PROGARM_STATUS.CREATE) {
      return TRMessage.info('新建方案无法进行导出操作，请保存后再导出');
    }
    if (!permissions.export) {
      return TRMessage.info('请联系管理员获取相关权限');
    }
    try {
      let data = await exportProgram(id);
      if (data.data.type.includes('application/json')) {
        let reader = new FileReader();
        reader.onload = function () {
          let res = reader.result;
          let result = JSON.parse(res); // blob格式转成json
          if (result?.statusCode === '410') {
            // 对应业务逻辑
            TRMessage.error(res.message || '方案已被删除，导出失败');
            // 重新刷新序列的方案列表
            dispatch({ type: 'rollingBatch/handleSearchEffect' });
          } else if (result?.statusCode !== HttpCode.SUCCESS) {
            TRMessage.error(res.message || '导出方案失败');
          }
        };
        reader.readAsText(data.data);
      } else {
        if (data.data && data.data instanceof Blob) {
          const realFileName = data.response.headers
            .get('content-disposition')
            .split('filename=')[1];
          downloadHandle(data.data, decodeURI(realFileName));
        } else {
          TRMessage.error('导出失败');
        }
      }
    } catch (e) {
      TRMessage.error('导出失败');
    }
  };

  /**
   * 设置定时申报时间及是否锁定
   * @param {*} lock
   * @param {*} time
   */
  const changeTimer = (lock, time) => {
    if (lock) {
      // 设置定时申报
      let obj = {
        ...timer,
        timerComVisible: false,
      };
      setTimer(obj);
      submitProgram(1, time);
    } else {
      // 取消定时申报
      dispatch({ type: 'rollingBatch/cancelTimelySubmit' });
    }
  };

  return (
    <div className={`${styles.main} border-radius-5`}>
      <div className={styles.tabAndOperate}>
        <div className={styles.mainTab}>
          <Tabs
            activeKey={currentProgramInfo?.id}
            onChange={(id) => changeCurrentProgram(id)}
            tabBarGutter={24}
          >
            {programList.map((item) => (
              <TabPane
                tab={
                  <div className={styles.tabPane}>
                    {renderProgramStatusIcon(item)}
                    <span>{item.title}</span>
                    {renderProgramDeleteIcon(item)}
                  </div>
                }
                key={item.id}
              />
            ))}
          </Tabs>
          <div
            className={`${styles.plusBtn} ${programList.length ? '' : styles.marginLeft0}`}
            onClick={addProgram}
          >
            <PlusOutlined className={styles.icon} />
            <span>新增</span>
          </div>
        </div>
        {programList.length ? (
          <div className={styles.mainOperate}>
            <Button
              onClick={() => {
                submitStatusRef.current.initHandle();
              }}
            >
              {' '}
              状态查询
            </Button>
            <Button
              onClick={() => {
                submitProgram(0);
              }}
              disabled={validSaveButtonDisabled()}
            >
              保存
            </Button>
            <Button
              onClick={() => {
                submitProgram(2);
              }}
              disabled={validSubmitButtonDisabled()}
            >
              立即申报
            </Button>
            <Button
              className={styles.timerBtn}
              type={validTimelyButtonDisabled() ? 'default' : 'primary'}
              onClick={handleTimer}
              onBlur={hideTimerCom}
              disabled={validTimelyButtonDisabled()}
            >
              {timer.lock ? (
                <>
                  <span>{timer.value.format(timer.format)}</span>
                  <img className={styles.lockIcon} src={lock} />
                </>
              ) : (
                '定时申报'
              )}
            </Button>
            {timer.timerComVisible ? (
              <div className={styles.timer}>
                <div className={styles.date}>
                  {moment(currentSequenceDate).format(SEQUENCE_TRADE_TIME_PATTERN)}
                </div>
                <TimePicker
                  popupClassName={styles.timerPopup}
                  open={true}
                  showNow={false}
                  value={timer.value}
                  format={timer.format}
                  disabledTime={() => getDisabledTimelyFuncJson(currentSequenceInfo)}
                  onChange={(time) => {
                    changeTimer(true, time);
                  }}
                />
              </div>
            ) : (
              ''
            )}
            <div className={styles.exportBtn} onClick={exportProgramAsync}>
              <UploadOutlined className={styles.icon} />
              <span>导出</span>
            </div>
          </div>
        ) : (
          ''
        )}
      </div>
      {programList.length ? <ProgramSetting /> : <TRDefault type="emptysm" />}
      <SubmitStatusModal ref={submitStatusRef} />
      <PowerValidationModal ref={powerValidationModalRef} />
      <TradeStrategyValidationModal ref={tradeStrategyValidationModalRef} />
    </div>
  );
};

export default connect(
  ({
    rollingBatch: {
      tradeCenterTime,
      programList,
      hasModified,
      selectedUnitIds,
      currentProgramInfo,
      currentProgramHourOrderList,
      powerLimitInfo,
      globalSequence: { date: currentSequenceDate, current: currentSequenceInfo },
      currentProgramPermission: permissions,
      currentUnitList,
    },
  }) => ({
    tradeCenterTime,
    programList,
    hasModified,
    selectedUnitIds,
    currentProgramInfo,
    currentSequenceDate,
    currentSequenceInfo,
    currentProgramHourOrderList,
    powerLimitInfo,
    permissions,
    currentUnitList,
  }),
)(Main);
